home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / contrib / campbell / bar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-27  |  7.0 KB  |  273 lines

  1. #include <stdio.h>
  2. #include "gsr.h"
  3.  
  4. #define DEBUG
  5. #undef DEBUG
  6.  
  7. char *ylabel="", *xlabel="", *title="", *term=NULL;
  8.  
  9. /* externs needed for getopt */
  10. extern char *optarg;
  11. extern int optind, opterr;  /* 0 opterr: print err message and return "?" */
  12.  
  13. /*
  14.    Do bar plots:
  15.       bar [-x xlabel] [-y ylabel] [-t title] [-T term] [file [file2 ...]]
  16. */
  17.  
  18. main(argc, argv)
  19. int argc;
  20. char *argv[];
  21. {
  22.    FILE *in, *fopen();
  23.    int c;
  24.  
  25. /* Check options. */
  26.    while ((c = getopt (argc, argv, "x:y:t:T:")) != EOF) {
  27.       switch (c) {
  28.       case 'x': 
  29.          xlabel = optarg;
  30.       break;
  31.       case 'y': 
  32.          ylabel = optarg;
  33.       break;
  34.       case 't': 
  35.          title = optarg;
  36.       break;
  37.       case 'T': 
  38.          term = optarg;
  39.       break;
  40.       case '?': 
  41.       default:
  42.          usage();
  43.       }
  44.    }
  45. /* Find out what terminal we're on to compute the max number of points. */
  46.    gt_init_terminal();
  47.    if (term != NULL) 
  48.       gt_change_term (term, -1);
  49.    if (GTterm == 0) {
  50.       fprintf (stderr, "Unknown terminal\n");
  51.       exit(1);
  52.    }
  53.  
  54.    if (argc <= optind) {
  55.       bar_graph(stdin);
  56.       if (isatty(fileno(stdout)) && isatty(fileno(stdin)))
  57.          getchar();
  58.    }
  59.    else {
  60.       for (; optind < argc; ++optind) {
  61.          if ((in = fopen (argv[optind], "r")) == NULL) {
  62.             fprintf (stderr, "Can't open %s\n", argv[optind]);
  63.             usage();
  64.          }
  65.          bar_graph(in);
  66.          if (isatty(fileno(stdout)) && isatty(fileno(stdin)))
  67.             getchar();
  68.       }
  69.    }
  70.    gsr_reset_terminal();
  71. }
  72.  
  73.  
  74. bar_graph(in)
  75. FILE *in;
  76. /* 
  77.    Routine to make a bar graph out of a list of points.  The list of
  78.    points come from the file named on the command line.
  79.  
  80.    Parameter:
  81.  
  82.           in:  Pointer to file descriptor containing list of points.
  83. */
  84. {
  85. #define MAXBUF 255
  86.    struct termentry *t = >term_tbl[GTterm];
  87.    int *pnum, bar_w, x_loc, height, lcnt, max_points;
  88.    int err, i, k, result, bar_cnt=0;
  89.    float *pval, scale, pmax, pmin, dummy;
  90.    char buf[MAXBUF];
  91.  
  92.    max_points = (t->xmax - 4*t->h_char)/2;
  93.  
  94. /* Read everything into an array of floats with room for 10 per line. */
  95.    pval = (float *)malloc (10*sizeof(float)*max_points);
  96.    pnum = (int *)malloc (sizeof(int )*max_points);
  97.    pmin = VERYLARGE;
  98.    pmax = -VERYLARGE;
  99.    err = 0;
  100.    for (lcnt=0; fgets (buf, MAXBUF, in) != NULL; ++lcnt) {
  101.       result = sscanf(buf,"%f %f %f %f %f %f %f %f %f %f %f", 
  102.         &pval[lcnt*10], &pval[lcnt*10+1], &pval[lcnt*10+2], &pval[lcnt*10+3], 
  103.         &pval[lcnt*10+4], &pval[lcnt*10+5], &pval[lcnt*10+6], &pval[lcnt*10+7], 
  104.         &pval[lcnt*10+8], &pval[lcnt*10+9], &dummy);
  105.       if (result > 10) {
  106.          err = 1;
  107.          break;
  108.       }
  109.    /* Find the max and min of the overall array. */
  110.       for (k = 0; k < result; ++k) {
  111.          if (pval[lcnt*10+k] > pmax) pmax = pval[lcnt*10+k];
  112.          if (pval[lcnt*10+k] < pmin) pmin = pval[lcnt*10+k];
  113.       }
  114.       pnum[lcnt] = result;  /* number of items on this line. */
  115.       bar_cnt += result;
  116.       if (bar_cnt > max_points) {
  117.          err = 1;
  118.          break;
  119.       }
  120.    }
  121.    if (bar_cnt >= max_points) {
  122.       fprintf (stderr, "Error on input: more than %d data elements\n", bar_cnt);
  123.       exit(1);
  124.    }
  125.    if (err) {
  126.       fprintf (stderr, "Error on input: line %d\n", lcnt);
  127.       exit(1);
  128.    }
  129.  
  130. /* Now that we know max and min, we can initialize the plotting device. */
  131.    gsr_init (stdout, 1.0, 100.0, pmin < 0.0 ? pmin : 0.0, pmax, 1, 1, 0, 0);
  132.  
  133. /* Draw the bars represented by the array pval. */
  134.    bar_plot (pval, pnum, lcnt, pmax, pmin);
  135. }
  136.  
  137.  
  138. usage()
  139. {
  140.    fprintf (stderr, 
  141. "usage: bar [-x xlabel] [-y ylabel] [-t title] [-T term] [file [file2 ...]]\n");
  142.    fprintf (stderr, "List of terminals (on standard output):\n");
  143.    gt_list_terms();
  144.    exit(1);
  145. }
  146.  
  147.  
  148. bar_plot (pval, pnum, lcnt, pmax, pmin)
  149. float pval[], pmax, pmin;
  150. int pnum[], lcnt;
  151. /*
  152.    Routine to draw the bars represented by values in array pval.
  153.  
  154.    Parameters:
  155.  
  156.          pval: array of groups of points to take as bar heights.
  157.  
  158.          pnum: array of the number of points in the ith bar group.
  159.  
  160.          lcnt: number of groups (10 at most per group) of bars to draw.
  161.  
  162.          pcnt: number of points to draw. 
  163.  
  164.          pmax: largest value in the pval array.
  165.  
  166.          pmin: smallest value in the pval array.
  167. */
  168. {
  169.    int i, j, k, bar_cnt, zero, bar_h, bar_w, x_loc;
  170.    struct termentry *t = >term_tbl[GTterm];
  171.  
  172. /* Compute the width of the bar graph. */
  173.    for (bar_cnt=i=0; i < lcnt; ++i)
  174.       bar_cnt += pnum[i]+1;
  175.  
  176.    bar_w = (GSRxright - GSRxleft)/bar_cnt;
  177.  
  178. /* Compute start of first bar. */
  179.    x_loc = (GSRxright - (bar_cnt-1)*bar_w)/2.0 + GSRxleft/2.0 + 0.5;
  180.  
  181.    zero = gsr_map_y (0.0);
  182.  
  183. #ifdef DEBUG
  184.    for (i=0; i < lcnt; ++i) {
  185.       fprintf (stderr, "%d: pval[%d] = ", pnum[i], i*10);
  186.       for (k=0; k < pnum[i]; ++k) {
  187.          fprintf (stderr, "%f ", pval[i*10+k]);
  188.       }
  189.       fprintf (stderr,"\n");
  190.    }
  191.    fprintf (stderr, "lcnt = %d\t", lcnt);
  192.    fprintf (stderr, "pmax = %f\t", pmax);
  193.    fprintf (stderr, "pmin = %f\n", pmin);
  194.    fprintf (stderr, "zero = %d\t", zero);
  195.    fprintf (stderr, "bar_cnt = %d\n", bar_cnt);
  196.    fprintf (stderr, "bar_w = %d\n", bar_w);
  197.    fprintf (stderr, "Hit return\n");
  198.    (void )getchar();
  199. #endif
  200.  
  201. /* Put device into graphics mode. */
  202.    gsr_graphics();
  203.  
  204. /* Draw a box around the plot. */
  205.    gsr_boundary();
  206.  
  207. /* Draw tics for the y axis of the plot. */
  208.    gsr_draw_tics (0, 0, 0, 1, 1, 1);
  209.  
  210. /* Write the ylabel, xlabel, and title to the plot. */
  211.    gsr_ylabel (ylabel);
  212.    gsr_xlabel (xlabel);
  213.    gsr_title  (title);
  214.  
  215. /* Draw the zero line (we might want a different line type here). */
  216.    if (pmin < 0.0)
  217.       gsr_draw_axis (0.0, 0.0, 2);  /* Just y axis */
  218.  
  219. /* Put the linetype back to something we expect. */
  220.    gsr_line_point_type (0, 0);
  221.  
  222. /* Draw lcnt bars of height pval[i] and width bar_w. */
  223.    for (i = 0; i < lcnt; ++i) {
  224.       for (k = 0; k < pnum[i]; ++k) {
  225.          bar_h = gsr_map_y (pval[i*10+k]);
  226.  
  227. #ifdef DEBUG
  228.          fprintf (stderr, "bar_h = %d, linetype = %d\n", bar_h, k);
  229. #endif
  230.    
  231.       /* Draw the bar's rectangle. */
  232.          (*t->move)(x_loc,zero);
  233.          (*t->vector)(x_loc, bar_h);
  234.          (*t->vector)(x_loc+bar_w, bar_h);
  235.          (*t->vector)(x_loc+bar_w, zero);
  236.  
  237.       /* Shade in the rectangle just drawn. */
  238.          if (k % 6 < 4) {
  239.             for (j=0; j < bar_w; ++j) {
  240.             /* Terminal drivers define points as unsigned int... */
  241.                (*t->move)(x_loc+j,zero);
  242.                if (j % (k % 4 + 1) == 0)
  243.                   (*t->vector)(x_loc+j,bar_h);
  244.             }
  245.          }
  246.          else {
  247.             int lower, upper;
  248.             if (zero < bar_h) {
  249.                lower = zero;
  250.                upper = bar_h;
  251.             }
  252.             else {
  253.                lower = bar_h;
  254.                upper = zero;
  255.             }
  256.             for (j=lower; j < upper; ++j) {
  257.                if (j % (k % 3 + 1) == 0) {
  258.                   (*t->move)(x_loc,j);
  259.                   (*t->vector)(x_loc+bar_w,j);
  260.                }
  261.             }
  262.          }
  263.          x_loc += bar_w;
  264.       }
  265.       x_loc += bar_w;
  266.    }
  267. /* Back into text mode (to see the plot generated) */
  268.    gsr_text();
  269. }
  270.  
  271.  
  272.  
  273.